package com.hst.capacity.application.biz.impl;

import com.hst.capacity.application.biz.JobPlatformBiz;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.order.base.BaseOrderEntity;
import com.hst.capacity.domain.model.entity.order.express.ExpressOrderEntity;
import com.hst.capacity.domain.model.entity.order.intercity.IntercityOrderEntity;
import com.hst.capacity.domain.model.entity.order.job.IntercityTaskEntity;
import com.hst.capacity.domain.model.entity.order.job.JobPlatformEntity;
import com.hst.capacity.domain.model.entity.order.job.ExpressTaskEntity;
import com.hst.capacity.domain.model.entity.order.job.SpecialTaskEntity;
import com.hst.capacity.domain.model.entity.order.pool.OrderPoolEntity;
import com.hst.capacity.domain.model.entity.order.specialcar.SpCarOrderEntity;
import com.hst.capacity.domain.model.entity.vehicle.VehicleTypeEntity;
import com.hst.capacity.domain.model.request.OrderParam;
import com.hst.capacity.domain.model.request.job.JobPlatformParam;
import com.hst.capacity.domain.model.response.DefaultVO;
import com.hst.capacity.domain.model.response.job.JobPlatformVO;
import com.hst.capacity.infra.convertor.JobPlatformConvertor;
import com.hst.capacity.infra.convertor.OrderConvertor;
import com.hst.capacity.infra.persistence.jpa.order.express.ExOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.intercity.IcOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.ExpressTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.IntercityTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.JobPlatformRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.SpecialTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.pool.OrderPoolRepository;
import com.hst.capacity.infra.persistence.jpa.order.specialcar.SpCarOrderRepository;
import com.hst.capacity.infra.persistence.jpa.vehicle.VehicleTypeRepository;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.NumUtil;
import com.hst.capacity.infra.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.hst.capacity.domain.model.response.DefaultVO.success;

@Service
public class JobPlatformBizImpl implements JobPlatformBiz {

    @Autowired
    private JobPlatformRepository jobRepository;

    @Autowired
    private ExOrderRepository exOrderRepository;

    @Autowired
    private SpCarOrderRepository specialCarOrderRepository;

    @Autowired
    private OrderPoolRepository orderPoolRepository;

    @Autowired
    private IcOrderRepository icOrderRepository;

    @Autowired
    private VehicleTypeRepository vehicleTypeRepository;

    @Autowired
    private ExpressTaskRepository expressTaskRepository;

    @Autowired
    private IntercityTaskRepository intercityTaskRepository;

    @Autowired
    private SpecialTaskRepository specialTaskRepository;

    @Override
    public DefaultVO findJobByIdDriver(JobPlatformParam param) {
        JobPlatformVO vo = JobPlatformConvertor.INSTANCE.convertView(jobRepository.findByIdDriver(param.getIdDriver()));
        if (vo != null) {
            switch (vo.getModuleType()) {
                case 0:
                    List<SpCarOrderEntity> spOrderLst = specialCarOrderRepository.findSpOrderInService(vo.getIdTask());
                    vo.setOrderLst(OrderConvertor.INSTANCE.spOrderLstToView(spOrderLst));
                    break;
                case 1:
                    List<IntercityOrderEntity> icOrderLst = icOrderRepository.findIcOrderInService(vo.getIdTask());
                    vo.setOrderLst(OrderConvertor.INSTANCE.icOrderLstToView(icOrderLst));
                    break;
                case 9:
                    List<ExpressOrderEntity> exOrderLst = exOrderRepository.findExOrderInService(vo.getIdTask());
                    vo.setOrderLst(OrderConvertor.INSTANCE.exOrderLstToView(exOrderLst));
                    break;
            }
        }
        return success(vo);
    }

    @Override
    public DefaultVO jobTaskSave(JobPlatformParam param) {
        JobPlatformEntity entity = jobRepository.findByIdDriver(param.getIdDriver());
        if (entity != null) {
            if (isWork(entity.getStatus())) {
                throw new BusinessException(4001,"任务大厅司机有任务未完成，请完成后再派单");
            }
        }
        return success(jobRepository.save(JobPlatformConvertor.INSTANCE.convertEntity(param)));
    };

    boolean isWork(int status) {
        boolean result = false;
        result = (status == 1 || status == 2 || status ==3) ? true : false;
        return result;
    }

    /**
     * 创建新任务
     * @param order
     * @param param
     * @return
     */
    @Override
    public JobPlatformEntity assignOrderToJob(BaseOrderEntity order, OrderParam param) {
        JobPlatformEntity task = jobRepository.findByIdDriver(param.getIdDriver());
        if ( task !=null && Constants.TaskStatus.DISPATCH_COMPLETE == task.getStatus()) {
            throw new BusinessException(5002, "当前司机派单已经完成，请指派其他司机");
            //return task;
        }

        VehicleTypeEntity vtDriver = vehicleTypeRepository.findByIdDriver(param.getIdDriver());
        //包车check车型是否匹配
        if (Constants.OrderCarpoolType.Chartered == order.getCarpoolType()){
            //用车类型不匹配
            if (param.getModuleType() == Constants.OrderModuleType.SPECIAL) {
                if (vtDriver.getIdVehicleType() != order.getIdVehicleType()) {
                    throw new BusinessException(5002, "乘客指定车型不一致，不能派单");
                }
            } else {
                VehicleTypeEntity vtOrder = vehicleTypeRepository.findByIdVehicleType(order.getIdVehicleType());
                if (vtDriver.getSeats() < vtOrder.getSeats()) {
                    throw new BusinessException(5002, "所派司机车型座位不能满足乘客人数");
                }
            }
        }

        // 没有司机任务时，创建新任务
        if (task == null) {
            // 创建新任务
            task = newJob(order, param);

        } else {
            // 有司机任务时，检索任务中执行的订单数
            //int taskOrderCnt = findCountByIdTask(task);
            int passengersInCarNumber = task.getPassengersIncarNumber();
            // 任务中执行的订单数是0时
            if (passengersInCarNumber <= 0) {
                // 无执行中订单时，删除任务
                delJob(task);
                // 创建新任务
                task = newJob(order, param);
            }

            // 任务中执行的订单数大于0时
            if (passengersInCarNumber > 0) {
                // 业务类型校验(城际，专车，快车)
                if (param.getModuleType() != task.getModuleType()) {
                    throw new BusinessException(5002, "有其他业务订单未完成，无法接实时订单");
                }
                // 当前任务是包车订单时，不能派单
                if (Constants.OrderCarpoolType.Chartered == task.getCarpoolType() ||
                        Constants.OrderCarpoolType.Chartered == order.getCarpoolType()) {
                    throw new BusinessException(5002,"已有订单，请指派其他司机");
                }
                // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
                passengersInCarNumber = task.getPassengersIncarNumber() + order.getPassengerNumber();
                // 在乘人数超过任务最多可乘坐人数
                if (passengersInCarNumber > (task.getSeating() - 1)) {
                    throw new BusinessException(5002,"乘客数超出最大人数，不能派单");
                }

                //更新任务信息(派单完成)
                updateJob(task, order);
            }
        }

        return task;
    }

    /**
     * 创建新任务
     * @param order
     * @param param
     * @return
     */
    @Override
    public JobPlatformEntity newJob(BaseOrderEntity order, OrderParam param){

        VehicleTypeEntity vt = vehicleTypeRepository.findByIdDriver(param.getIdDriver());
        if (vt == null)
            throw new BusinessException(5002, "司机没有绑定车辆，请确认。");

        // 在乘人数超过任务最多可乘坐人数
        if (order.getPassengerNumber() > (vt.getSeats()-1))
            throw new BusinessException(5002,"乘客数超出最大人数，不能派单");

        JobPlatformEntity task = new JobPlatformEntity();
        task.setIdTask(StringUtil.generateUuid());
        task.setModuleType(param.getModuleType());
        task.setIdDriver(param.getIdDriver());
        if (Constants.OrderModuleType.EXPRESS == param.getModuleType()) {
            task.setRegionCode(((ExpressOrderEntity) order).getRegionCode());
        }
        task.setIdLine(order.getIdLine());
        task.setIdSchedule("");
        task.setScheduleTime(DateUtil.getNowTime());
        task.setIdFranchisee(order.getIdFranchisee());
        task.setIdShareRoute("");
        task.setQueueNum(0);
        task.setSeating(vt.getSeats());
        task.setPassengersNumber(0);
        task.setPassengersIncarNumber(order.getPassengerNumber());
        task.setTransportedPassengersNumber(0);
        task.setTaskSumMoney(NumUtil.getFloat(order.getEstimatedMoney()));
        task.setTaskAdditionalMoney(NumUtil.getFloat(order.getAdditionalMoney()));
        task.setTaskCouponMoney(NumUtil.getFloat(order.getCouponDiscount()));
        // carpool_type 0:拼车，1:包车
        task.setCarpoolType(order.getCarpoolType());
        // 派单中
        if (order.getCarpoolType() == Constants.OrderCarpoolType.Chartered)
            task.setStatus(Constants.TaskStatus.DISPATCH_COMPLETE);
        else
            task.setStatus(Constants.TaskStatus.COLLAGE);
        task.setTaskSubsidy(0F);
        task.setTaskNoLoadSubsidy(0F);

        task = jobRepository.saveAndFlush(task);

        return task;
    }

    /**
     * 更新任务
     * @param task
     * @param order
     * @return
     */
    @Override
    public void updateJob(JobPlatformEntity task,BaseOrderEntity order){
        // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
        Integer passengersInCarNumber = task.getPassengersIncarNumber() + order.getPassengerNumber();
        // 在乘人数超过任务最多可乘坐人数
        if (passengersInCarNumber > (task.getSeating()-1))
            throw new BusinessException(5002,"乘客数超出最大人数，不能派单");

        // 预估金额
        Float taskSumMoney = NumUtil.getFloat(task.getTaskSumMoney()) + NumUtil.getFloat(order.getEstimatedMoney());
        // 任务额外金额
        Float taskAdditionalMoney = NumUtil.getFloat(task.getTaskAdditionalMoney()) + NumUtil.getFloat(order.getAdditionalMoney());
        // 任务优惠金额
        Float taskCouponMoney = NumUtil.getFloat(task.getTaskCouponMoney()) + NumUtil.getFloat(order.getCouponDiscount());

        // 派单中
        if (order.getCarpoolType() == Constants.OrderCarpoolType.Chartered
        || passengersInCarNumber == (task.getSeating()-1)) {
            task.setStatus(Constants.TaskStatus.DISPATCH_COMPLETE);
        } else {
            task.setStatus(Constants.TaskStatus.COLLAGE);
        }
        task.setPassengersIncarNumber(passengersInCarNumber);
        task.setScheduleTime(DateUtil.getNowTime());
        task.setTaskSumMoney(taskSumMoney);
        task.setTaskAdditionalMoney(taskAdditionalMoney);
        task.setTaskCouponMoney(taskCouponMoney);

        jobRepository.saveAndFlush(task);
    }

    /**
     * 删除任务
     * @param task
     * @return
     */
    @Override
    public void delJob(JobPlatformEntity task){
        // 已运送乘客数大于0时，任务移动到历史表
        if (task.getTransportedPassengersNumber() > 0) {
            // 已完成订单移动到历史表
            switch (task.getModuleType()) {
                case Constants.OrderModuleType.SPECIAL:
                    SpecialTaskEntity spTask= JobPlatformConvertor.INSTANCE.convertJobPlatformSpEntity(task);
                    specialTaskRepository.save(spTask);
                    break;
                case Constants.OrderModuleType.INTERCITY:
                    IntercityTaskEntity icTask= JobPlatformConvertor.INSTANCE.convertJobPlatformIcEntity(task);
                    intercityTaskRepository.save(icTask);
                    break;
                case Constants.OrderModuleType.EXPRESS:
                    ExpressTaskEntity exTask= JobPlatformConvertor.INSTANCE.convertJobPlatformExEntity(task);
                    expressTaskRepository.save(exTask);
                    break;
            }
        }
        jobRepository.delete(task);
    }

    /**
     * 取消订单时更新任务
     * @param order
     * @return
     */
    @Override
    public void cancelOrder(BaseOrderEntity order){

        if (StringUtil.isBlank(order.getIdTask()))
            return;

        if (StringUtil.isBlank(order.getIdDriver()))
            return;

        // 司机当前任务取得
        JobPlatformEntity task = jobRepository.findByIdDriver(order.getIdDriver());

        if (task == null)
            return;

        if (StringUtil.isNotBlank(order.getIdTask()) && order.getIdTask().equals(task.getIdTask())) {
            // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）- 当前派单的订单人数
            Integer passengersInCarNumber = task.getPassengersIncarNumber() - order.getPassengerNumber();
            // 预估金额
            Float taskSumMoney = NumUtil.getFloat(task.getTaskSumMoney()) - NumUtil.getFloat(order.getEstimatedMoney());
            // 任务额外金额
            Float taskAdditionalMoney = NumUtil.getFloat(task.getTaskAdditionalMoney()) - NumUtil.getFloat(order.getAdditionalMoney());
            // 任务优惠金额
            Float taskCouponMoney = NumUtil.getFloat(task.getTaskCouponMoney()) - NumUtil.getFloat(order.getCouponDiscount());

            int taskOrderCnt = findCountByIdTask(task);
            if (taskOrderCnt > 1) {
                // 派单中
                task.setStatus(Constants.TaskStatus.COLLAGE);
            } else {
                // 任务下线
                task.setStatus(Constants.TaskStatus.OFFLINE);
            }

            task.setPassengersIncarNumber(passengersInCarNumber);
            task.setTaskSumMoney(taskSumMoney);
            task.setTaskAdditionalMoney(taskAdditionalMoney);
            task.setTaskCouponMoney(taskCouponMoney);
//        task.setScheduleTime(DateUtil.getNowTime());

            jobRepository.save(task);
        }
    }

    /**
     * 拒绝订单时更新任务
     * @param order
     * @return
     */
    @Override
    public void rejectOrder(BaseOrderEntity order){
        cancelOrder(order);
    }

    /**
     * 订单结束时更新任务
     * @param order
     * @return
     */
    @Override
    public void finishOrder(BaseOrderEntity order){

        // 司机当前任务取得
        JobPlatformEntity task = jobRepository.findByIdDriver(order.getIdDriver());

        if (task == null)
            return;

        if (StringUtil.isNotBlank(order.getIdTask()) && order.getIdTask().equals(task.getIdTask())) {
            // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）- 当前派单的订单人数
            Integer passengersInCarNumber = task.getPassengersIncarNumber() - order.getPassengerNumber();
            // 预估金额
            int transportedPassengersNumber = NumUtil.getInteger(task.getPassengersIncarNumber()) + NumUtil.getInteger(order.getPassengerNumber());
//        // 预估金额
//        Float taskSumMoney = NumUtil.getFloat(task.getTaskSumMoney()) - NumUtil.getFloat(order.getEstimatedMoney());
//        // 任务额外金额
//        Float taskAdditionalMoney = NumUtil.getFloat(task.getTaskAdditionalMoney()) - NumUtil.getFloat(order.getAdditionalMoney());
//        // 任务优惠金额
//        Float taskCouponMoney = NumUtil.getFloat(task.getTaskCouponMoney()) - NumUtil.getFloat(order.getCouponDiscount());

//        int taskOrderCnt = findCountByIdTask(task);
            if (passengersInCarNumber > 1) {
                // 服务中
                task.setStatus(Constants.TaskStatus.IN_SERVICE);
            } else {
                // 任务完成
                task.setStatus(Constants.TaskStatus.DISPATCH_COMPLETE);
            }

            task.setPassengersIncarNumber(passengersInCarNumber);
            task.setTransportedPassengersNumber(transportedPassengersNumber);
//        task.setTaskSumMoney(taskSumMoney);
//        task.setTaskAdditionalMoney(taskAdditionalMoney);
//        task.setTaskCouponMoney(taskCouponMoney);
//        task.setScheduleTime(DateUtil.getNowTime());

            // 有司机任务时，检索任务中执行的订单数
            //int taskOrderCnt = findCountByIdTask(task);
            // 任务中执行的订单数是0时
            if (task.getPassengersIncarNumber() == 0) {
                // 无执行中订单时，删除任务
                delJob(task);
            } else {
                jobRepository.save(task);
            }
        }
    }

    /**
     * 删除任务
     * @param idDriver
     * @return
     */
    @Override
    public boolean refreshDriverJob(String idDriver) {

        JobPlatformEntity task = jobRepository.findByIdDriver(idDriver);

        if (task != null) {
            switch (task.getModuleType()) {
                case Constants.OrderModuleType.SPECIAL:
                    List<OrderPoolEntity> orderListSp = orderPoolRepository.findByIdDriverAndIdTask(idDriver, task.getIdTask());
                    if (orderListSp.size()==0) {
                        delJob(task);
                    }else{
                        task = doRefreshDriverTaskSp(task, orderListSp);
                    }
                    break;
                case Constants.OrderModuleType.INTERCITY:
                    List<IntercityOrderEntity> orderListIc = icOrderRepository.findByIdDriverAndIdTask(idDriver, task.getIdTask());
                    if (orderListIc.size()==0) {
                        delJob(task);
                    }else{
                        task = doRefreshDriverTaskIc(task, orderListIc);
                    }
                    break;
                case Constants.OrderModuleType.EXPRESS:
                    List<ExpressOrderEntity> orderListEx = exOrderRepository.findByIdDriverAndIdTask(idDriver, task.getIdTask());
                    if (orderListEx.size()==0) {
                        delJob(task);
                    } else {
                        task = doRefreshDriverTaskEx(task, orderListEx);
                    }
                    break;
            }
        }
        return true;
    }

    /**
     * 重置任务信息（快车）
     * @param task
     * @param orderList
     * @return
     */
    private JobPlatformEntity doRefreshDriverTaskEx(JobPlatformEntity task,List<ExpressOrderEntity> orderList){
        Integer passengers_incar_number = 0;
        Float taskSumMoney = 0f;
        Float taskAdditionalMoney = 0f;
        Float task_coupon_money = 0f;
        for (ExpressOrderEntity row:orderList) {
            // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
            passengers_incar_number  = passengers_incar_number + row.getPassengerNumber();
            // 预估金额
            taskSumMoney = taskSumMoney + NumUtil.getFloat(row.getEstimatedMoney());
            // 任务额外金额
            taskAdditionalMoney = taskAdditionalMoney + NumUtil.getFloat(row.getAdditionalMoney());
            // 任务优惠金额
            task_coupon_money = task_coupon_money + NumUtil.getFloat(row.getCouponDiscount());
        }
        task.setPassengersIncarNumber(passengers_incar_number);
        task.setTaskSumMoney(taskSumMoney);
        task.setTaskAdditionalMoney(taskAdditionalMoney);
        task.setTaskCouponMoney(task_coupon_money);
        task.setUpdateBy(Constants.Def_CreateBy);
        task = jobRepository.saveAndFlush(task);
        return task;
    }

    /**
     * 重置任务信息（城际）
     * @param task
     * @param orderList
     * @return
     */
    private JobPlatformEntity doRefreshDriverTaskIc(JobPlatformEntity task,List<IntercityOrderEntity> orderList){
        Integer passengers_incar_number = 0;
        Float taskSumMoney = 0f;
        Float taskAdditionalMoney = 0f;
        Float task_coupon_money = 0f;
        for (IntercityOrderEntity row:orderList) {
            // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
            passengers_incar_number  = passengers_incar_number + row.getPassengerNumber();
            // 预估金额
            taskSumMoney = taskSumMoney + NumUtil.getFloat(row.getEstimatedMoney());
            // 任务额外金额
            taskAdditionalMoney = taskAdditionalMoney + NumUtil.getFloat(row.getAdditionalMoney());
            // 任务优惠金额
            task_coupon_money = task_coupon_money + NumUtil.getFloat(row.getCouponDiscount());
        }
        task.setPassengersIncarNumber(passengers_incar_number);
        task.setTaskSumMoney(taskSumMoney);
        task.setTaskAdditionalMoney(taskAdditionalMoney);
        task.setTaskCouponMoney(task_coupon_money);
        task.setUpdateBy(Constants.Def_CreateBy);
        task = jobRepository.saveAndFlush(task);
        return task;
    }

    /**
     * 重置任务信息（订单池）
     * @param task
     * @param orderList
     * @return
     */
    private JobPlatformEntity doRefreshDriverTaskSp(JobPlatformEntity task,List<OrderPoolEntity> orderList){
        Integer passengers_incar_number = 0;
        Float taskSumMoney = 0f;
        Float taskAdditionalMoney = 0f;
        Float task_coupon_money = 0f;
        for (OrderPoolEntity row:orderList) {
            // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
            passengers_incar_number  = passengers_incar_number + row.getPassengerNumber();
            // 预估金额
            taskSumMoney = taskSumMoney + NumUtil.getFloat(row.getEstimatedMoney());
            // 任务额外金额
            taskAdditionalMoney = taskAdditionalMoney + NumUtil.getFloat(row.getAdditionalMoney());
            // 任务优惠金额
            task_coupon_money = task_coupon_money + NumUtil.getFloat(row.getCouponDiscount());
        }
        task.setPassengersIncarNumber(passengers_incar_number);
        task.setTaskSumMoney(taskSumMoney);
        task.setTaskAdditionalMoney(taskAdditionalMoney);
        task.setTaskCouponMoney(task_coupon_money);
        task.setUpdateBy(Constants.Def_CreateBy);
        task = jobRepository.saveAndFlush(task);
        return task;
    }

    /**
     * 查找任务中正在执行的订单数量
     * @param task
     * @return
     */
    private int findCountByIdTask(JobPlatformEntity task){
        int taskOrderCnt = 0;
        switch (task.getModuleType()) {
            case Constants.OrderModuleType.SPECIAL:
                taskOrderCnt = specialCarOrderRepository.findCountByIdTask(task.getIdTask());
                break;
            case Constants.OrderModuleType.INTERCITY:
                taskOrderCnt = icOrderRepository.findCountByIdTask(task.getIdTask());
                break;
            case Constants.OrderModuleType.EXPRESS:
                taskOrderCnt = exOrderRepository.findCountByIdTask(task.getIdTask());
                break;
        }
        return taskOrderCnt;
    }

}
